/*
 * MPlayer.cpp
 *
 *  Created on: 2018年9月4日
 *      Author: zhengboyuan
 */

#include "MPlayer.h"
#include "TStringUtil.h"



MPlayer::MPlayer():
	m_handle(),
	m_canPlay(),
	m_faceAnalyzer()
{
}

MPlayer::~MPlayer()
{
	close();
}

bool MPlayer::open(const std::string& url)
{
#ifdef WIN32
	m_videoWindow.open("Video");
#endif //WIN32

	int rc = m_reader.open(url.c_str());
	if (rc != 0)
	{
		return false;
	}

	m_handle = MDecode_CreateHandle();

	MDecode_SetParam(m_handle, "source.dump", "1");

	MDecode_Format fmt = MDecode_Format();
	fmt.codec = (MDecode_CodecType)m_reader.m_codec;
	fmt.prop = (uint8_t*)(m_reader.m_prop.c_str());
	fmt.propSize = m_reader.m_prop.size();

	fmt.channels = m_reader.m_channels;
	fmt.samplerate = m_reader.m_sampleRate;
	//fmt.audioCodec = (MDecode_CodecType)m_reader.m_acodec;

	BOOL ret = MDecode_OpenStream(m_handle, &fmt);

	//MDecode_SetDecodeCallback(handle, MDECODE_PIXEL_I420, Application::decodeCallback, &app);
	//MDecode_SetDecodeCallbackFreq(handle, 10);
	MDecode_SetDelayTime(m_handle, 1000 * 2);
	MDecode_SetFaceTrackDuration(500);

#ifdef WIN32
	MDecode_SetVideoWnd(m_handle, m_videoWindow.getHwnd());
#endif //WIN32

	MDecode_Play(m_handle);


	m_faceAnalyzer.open(fmt);
	m_faceAnalyzer.setSink(this);

	return start();
}

void MPlayer::close()
{
	if (isRunning())
	{
		stop();
	}

	MDecode_Stop(m_handle);
	MDecode_CloseStream(m_handle);
	MDecode_DestroyHandle(m_handle);

	m_reader.close();
	m_pktQueue.clear();

	m_faceAnalyzer.close();
	
#ifdef WIN32
	m_videoWindow.close();
#endif //WIN32
}

HANDLE MPlayer::getHandle()
{
	return m_handle;
}

void MPlayer::inputSubtitle(const std::string& text, int64_t pts)
{
	MDecode_InputData(m_handle, MDECODE_MEDIA_SUBTITLE, (const uint8_t*)text.c_str(), text.size(), pts, 0);
}

int MPlayer::run()
{
	while (!m_canExit)
	{
		AVPacketPtr pkt(new AVPacket());
		av_init_packet(pkt.get());
		int rc = m_reader.read(*pkt.get());

		if (rc != 0)
		{
			break;
		}

		if (pkt->stream_index > 0)
		{
			continue;
		}

		onInputPacket(pkt);

		m_pktQueue.push(pkt);

		if (m_canPlay)
		{
			pkt = m_pktQueue.pop();
			if (pkt)
			{
				MDecode_InputData(m_handle, pkt->stream_index, pkt->data, pkt->size, pkt->pts, pkt->flags);
			}
		}
	}
	return 0;
}

void MPlayer::doStop()
{
	m_event.post();
}

void MPlayer::onInputPacket(AVPacketPtr& pkt)
{
	m_faceAnalyzer.input(pkt->stream_index, pkt->data, pkt->size, pkt->pts, pkt->flags);
}

void MPlayer::play()
{
	m_canPlay = true;
}

void MPlayer::pause()
{
	m_canPlay = false;
}

void MPlayer::onFace(const std::string& text, int64_t pts)
{
	MDecode_InputData(m_handle, MDECODE_MEDIA_SUBTITLE, (const uint8_t*)text.c_str(), text.size(), pts, 0);
}